package com.sencorsta.utils.net;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sencorsta.utils.date.DateUtil;
import com.sencorsta.utils.string.Md5Tools;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 * HTTP请求对象
 */
public class HttpRequester {

	private String defaultContentEncoding;

	public HttpRequester() {
		this.defaultContentEncoding = "utf-8";
	}

	public HttpRequester(String encoding) {
		this.defaultContentEncoding = encoding;
	}

	/**
	 * 发送GET请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendGet(String urlString) throws IOException {
		return this.send(urlString, "GET", null, null);
	}

	/**
	 * 发送GET请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendGet(String urlString, JSONObject params) throws IOException {
		return this.send(urlString, "GET", params, null);
	}

	/**
	 * 发送GET请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @param propertys
	 *            请求属性
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendGet(String urlString, JSONObject params, JSONObject propertys) throws IOException {
		return this.send(urlString, "GET", params, propertys);
	}

	/**
	 * 发送POST请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendPost(String urlString) throws IOException {
		return this.send(urlString, "POST", null, null);
	}

	/**
	 * 发送POST请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendPost(String urlString, JSONObject params) throws IOException {
		return this.send(urlString, "POST", params, null);
	}
	
	
	public HttpRespons sendPost(String url, String params) throws IOException {
		return this.sendXML(url, "POST", params, null);
	}
	private HttpRespons sendXML(String urlString, String method, String parameters, Object propertys) throws IOException {
		HttpURLConnection urlConnection = null;

		URL url = new URL(urlString);
		urlConnection = (HttpURLConnection) url.openConnection();

		urlConnection.setRequestMethod(method);
		urlConnection.setDoOutput(true);
		urlConnection.setDoInput(true);
		urlConnection.setUseCaches(false);
		urlConnection.setConnectTimeout(3000);
		urlConnection.setReadTimeout(5000);


		if (method.equalsIgnoreCase("POST") && parameters != null) {
			OutputStream output = urlConnection.getOutputStream();
			output.write(parameters.getBytes(defaultContentEncoding));
			output.flush();
			output.close();
		}

		return this.makeContent(urlString, urlConnection);
	}


	/**
	 *
	 * @param httpUrl  请求的url
	 * @param param  form表单的参数（key,value形式）
	 * @return
	 */
	public HttpRespons sendPostForm(String httpUrl, Map param) {

		HttpURLConnection connection = null;
		InputStream is = null;
		OutputStream os = null;
		BufferedReader br = null;
		String result = null;
		try {
			URL url = new URL(httpUrl);
			// 通过远程url连接对象打开连接
			connection = (HttpURLConnection) url.openConnection();
			// 设置连接请求方式
			connection.setRequestMethod("POST");
			// 设置连接主机服务器超时时间：15000毫秒
			connection.setConnectTimeout(15000);
			// 设置读取主机服务器返回数据超时时间：60000毫秒
			connection.setReadTimeout(60000);

			// 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
			connection.setDoOutput(true);
			// 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无
			connection.setDoInput(true);
			// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			// 设置鉴权信息：Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
			//connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
			// 通过连接对象获取一个输出流
			os = connection.getOutputStream();
			// 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的(form表单形式的参数实质也是key,value值的拼接，类似于get请求参数的拼接)

			List<String> keys = new ArrayList<String>(param.keySet());
			Collections.sort(keys);

			StringBuilder prestr = new StringBuilder();
			for (int i = 0; i < keys.size(); i++) {
				String key = keys.get(i);
				String value = (String)param.get(key);
				if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
					prestr.append(key).append("=").append(value);
				} else {
					prestr.append(key).append("=").append(value).append("&");
				}
			}

			os.write(prestr.toString().getBytes());
//			// 通过连接对象获取一个输入流，向远程读取
//			if (connection.getResponseCode() == 200) {
//
//				is = connection.getInputStream();
//				// 对输入流对象进行包装:charset根据工作项目组的要求来设置
//				br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//
//				StringBuffer sbf = new StringBuffer();
//				String temp = null;
//				// 循环遍历一行一行读取数据
//				while ((temp = br.readLine()) != null) {
//					sbf.append(temp);
//					sbf.append("\r\n");
//				}
//				result = sbf.toString();
//			}
			return this.makeContent(httpUrl, connection);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != os) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != is) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			// 断开与远程地址url的连接
			connection.disconnect();

		}
		return null;
	}

	/**
	 * 发送POST请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @param propertys
	 *            请求属性
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendPost(String urlString, JSONObject params, JSONObject propertys) throws IOException {
		return this.send(urlString, "POST", params, propertys);
	}

	/**
	 * 发送HTTP请求
	 * 
	 * @param urlString
	 * @return 响映对象
	 * @throws IOException
	 */
	public int timeOutConnect=3000;
	public int timeOutRead=5000;
	public boolean doOutput=true;
	public boolean doInput=true;
	public boolean useCaches=false;


	private HttpRespons send(String urlString, String method, JSONObject parameters, JSONObject propertys)
			throws IOException {
		HttpURLConnection urlConnection = null;

		if (method.equalsIgnoreCase("GET") && parameters != null) {
			StringBuilder param = new StringBuilder();
			boolean flag = urlString.indexOf("?") < 0;
			for (String key : parameters.keySet()) {
				if (flag) {
					flag = false;
					param.append("?");
				} else {
					param.append("&");
				}
				param.append(key).append("=").append(parameters.get(key));
			}
			urlString += param;
		}
		URL url = new URL(urlString);
		urlConnection = (HttpURLConnection) url.openConnection();

		urlConnection.setRequestMethod(method);
		urlConnection.setDoOutput(doOutput);
		urlConnection.setDoInput(doInput);
		urlConnection.setUseCaches(useCaches);
		urlConnection.setConnectTimeout(timeOutConnect);
		urlConnection.setReadTimeout(timeOutRead);

		if (propertys != null)
			for (String key : propertys.keySet()) {
				urlConnection.addRequestProperty(key, propertys.get(key).toString());
			}

		if (method.equalsIgnoreCase("POST") && parameters != null) {
			StringBuilder param = new StringBuilder();
			for (String key : parameters.keySet()) {
				param.append(key).append("=").append(parameters.get(key));
				param.append("&");
			}
			OutputStream output = urlConnection.getOutputStream();
			output.write(param.toString().getBytes(defaultContentEncoding));
			output.flush();
			output.close();
		}

		return this.makeContent(urlString, urlConnection);
	}

	/**
	 * 得到响应对象
	 * 
	 * @param urlConnection
	 * @return 响应对象
	 * @throws IOException
	 */
	private HttpRespons makeContent(String urlString, HttpURLConnection urlConnection) throws IOException {
		HttpRespons httpResponser = new HttpRespons();
		try {
			String ecod = urlConnection.getContentEncoding();
			if (ecod == null)
				ecod = this.defaultContentEncoding;
			
			InputStream in = urlConnection.getInputStream();
			int lenght=in.available();
//			System.out.println("httpResponseLenght=-============="+lenght);
			byte[] bytes = new byte[lenght];
			in.read(bytes);
//			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in,"utf-8"));
//			httpResponser.contentCollection = new Vector<String>();
//			StringBuilder temp = new StringBuilder();
//			String line = bufferedReader.readLine();
//			while (line != null) {
//				httpResponser.contentCollection.add(line);
//				temp.append(line);
//				line = bufferedReader.readLine();
//			}
//			bufferedReader.close();

			

			httpResponser.urlString = urlString;

			httpResponser.defaultPort = urlConnection.getURL().getDefaultPort();
			httpResponser.file = urlConnection.getURL().getFile();
			httpResponser.host = urlConnection.getURL().getHost();
			httpResponser.path = urlConnection.getURL().getPath();
			httpResponser.port = urlConnection.getURL().getPort();
			httpResponser.protocol = urlConnection.getURL().getProtocol();
			httpResponser.query = urlConnection.getURL().getQuery();
			httpResponser.ref = urlConnection.getURL().getRef();
			httpResponser.userInfo = urlConnection.getURL().getUserInfo();

			httpResponser.content = new String(bytes, ecod);
			httpResponser.contentEncoding = ecod;
			httpResponser.code = urlConnection.getResponseCode();
			httpResponser.message = urlConnection.getResponseMessage();
			httpResponser.contentType = urlConnection.getContentType();
			httpResponser.method = urlConnection.getRequestMethod();
			httpResponser.connectTimeout = urlConnection.getConnectTimeout();
			httpResponser.readTimeout = urlConnection.getReadTimeout();

			return httpResponser;
		} catch (IOException e) {
			throw e;
		} finally {
			if (urlConnection != null) urlConnection.disconnect();
		}
	}

	/**
	 * 默认的响应字符集
	 */
	public String getDefaultContentEncoding() {
		return this.defaultContentEncoding;
	}

	/**
	 * 设置默认的响应字符集
	 */
	public void setDefaultContentEncoding(String defaultContentEncoding) {
		this.defaultContentEncoding = defaultContentEncoding;
	}


	public static final String merNo = "1011761367005";// 商户号
	public static final String key_Pay = "b4f28dd8913f4b8694ab721397439b13";// 签名MD5密钥,24位
	public static final String URL_Pay = "http://39.98.89.184:9901/gateway/pay";

	public static void main(String[] args) {
		String ddd="123\\456";
		System.out.println(ddd.replaceAll("\\\\",""));

		//商户订单号
		String out_trade_no = "PC" + new Date().getTime();
		//订单金额
		String total_fee = "1000";
		//异步通知URL
		String notify_url = "http://www.baidu.com";
		//同步跳转URL
		String return_url = "http://www.baidu.com";
		//ip
		String ip = "";
		String timestamp = "" + new Date().getTime();
		String sign = "";


		Map<String, String> metaSignMap = new TreeMap<String, String>();
		metaSignMap.put("mch_id", merNo);
		metaSignMap.put("pay_type", "KUAI_PAY_H5");
		metaSignMap.put("out_trade_no", out_trade_no);
		metaSignMap.put("total_fee", total_fee);
		metaSignMap.put("trade_date", DateUtil.getTime("yyyyMMddHHmmss"));
		metaSignMap.put("card_code", "6214851218351356");
		metaSignMap.put("card_name", "戴斌");
		metaSignMap.put("id_card", "53040219890825003X");
		metaSignMap.put("bank_code", "0308");
		metaSignMap.put("channel", "1");
		metaSignMap.put("mch_create_ip", "192.168.0.1");
		metaSignMap.put("notify_url", notify_url);
		metaSignMap.put("return_url", return_url);
		metaSignMap.put("nonce_str", "DKSK");


		String signStr = sign(metaSignMap);
		metaSignMap.put("sign", signStr);
		//metaSignMap.put("return_type",return_type);

		System.out.println("signStr:" + signStr);

		String jsonStr = JSONObject.toJSONString(metaSignMap);
		System.out.println("jsonStr:" + jsonStr);
		JSONObject jsonObj = JSON.parseObject(jsonStr);

		HttpRequester requester = new HttpRequester();
		HttpRespons respons = null;
		try {

//            String resultJsonStr =ToolKit.request(URL_Pay, jsonStr);
//            System.out.println(resultJsonStr);
			respons = requester.sendPostForm(URL_Pay, metaSignMap);
			System.out.println("respons:" + respons.getContent());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String sign(Map map) {
		String head = "apiKey=" + key_Pay;
		for (Object o : map.keySet()) {
			head += "&" + o + "=" + map.get(o);
		}
		System.out.println(head);
		return Md5Tools.MD5(head).toUpperCase();
	}
	
	
}